#include "LiteMiddle.h"

#define LITELOG_UARTTX      g_tUart4        //  LOG串口

LITELOG_T g_tLiteLog;                           //  LOG业务句柄
static MessageBufferHandle_t  s_xMsgBufLogTx;   //  消息缓冲区：日志输出
static SemaphoreHandle_t      s_xMutexLogTx;    //  信号量：日志输出

//  Log模块初始化
void LITE_LOG_Init(void)
{
  g_tLiteLog.tpUart = &LITELOG_UARTTX;        //  缺省配置
  
  s_xMsgBufLogTx  = xMessageBufferCreate(g_tLiteLog.tpUart->tpTxBuf->size); //  消息队列尺寸为发送缓冲区尺寸
  g_tLiteLog.tpxMsgBufLogTx = s_xMsgBufLogTx; //  缺省配置
  
  s_xMutexLogTx =  xSemaphoreCreateBinary();  //  创建信号量
  xSemaphoreGive(s_xMutexLogTx);              //  初始释放一次
  g_tLiteLog.tpxMutexLogTx  =  s_xMutexLogTx; //  缺省配置
  
  //step 断言保护，为假触发断言
  configASSERT(g_tLiteLog.tpxMsgBufLogTx);    
  configASSERT(g_tLiteLog.tpxMutexLogTx);
  return;
}
/*
*********************************************************************************************************
* 函 数 名:   LITE_LOG_Write
* 功能说明:   原始数据接口（用于直接写入帧），写入消息缓存区
* 形    参:   
* 返 回 值:   无
*********************************************************************************************************
*/
void LITE_LOG_Write(const void *data, u16 len)
{
  if ( len>0 && len <= BUF_GetRemainSize(g_tLiteLog.tpUart->tpTxBuf)) 
  {
    xMessageBufferSend(g_tLiteLog.tpxMsgBufLogTx, data, len, pdMS_TO_TICKS(1000)); //  超时未写入则放弃写入
  }
  return;
}

/*
*********************************************************************************************************
* 函 数 名:   LITE_LOG_Send
* 功能说明:  
* 形    参:   
* 返 回 值:   无
*********************************************************************************************************
*/
void LITE_LOG_Send(u8 *pData,u16 Size)
{
  xSemaphoreTake(g_tLiteLog.tpxMutexLogTx,portMAX_DELAY);   //  取外设锁——线程安全
  
  if(IS_FLAG_SET(g_tLiteLog.tpUart->state,UART_TX_DONE))
  {
    HAL_UART_Transmit_DMA(g_tLiteLog.tpUart->tpUart,pData,Size);  //  速发方案，不写入串口缓存，直接发送
    CLEAR_FLAG(g_tLiteLog.tpUart->state,UART_TX_DONE);            //  置位串口锁——辅助验证
  } 
  return;
}

//  日志输出中断函数
void LITE_LOG_TxHandler(UART_HandleTypeDef *huart)
{
  //  保护
  if(huart != g_tLiteLog.tpUart->tpUart)  return;                       
  BUF_DelData(g_tLiteLog.tpUart->tpTxBuf);                  //  删除发送缓存区数据
  SET_FLAG(g_tLiteLog.tpUart->state,UART_TX_DONE);          //  清空串口锁——辅助验证
  
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  xSemaphoreGiveFromISR(g_tLiteLog.tpxMutexLogTx,&xHigherPriorityTaskWoken);  //  释放外设锁——线程安全
  
  return;
}

//  日志输入中断函数
void LITE_LOG_RxHandler(UART_HandleTypeDef *huart,uint16_t Size)
{
  //  保护
  if(huart != g_tLiteLog.tpUart->tpUart)  return;
  
  //  step1:标记一次接收
  SET_FLAG(g_tLiteLog.tpUart->state,UART_RX_DONE); 
  g_tLiteLog.tpUart->tpRxBuf->length  = Size;

  //  step2：继续开启下一次接收
  HAL_UARTEx_ReceiveToIdle_DMA(g_tLiteLog.tpUart->tpUart,g_tLiteLog.tpUart->tpRxBuf->data,g_tLiteLog.tpUart->tpRxBuf->size);
  __HAL_DMA_DISABLE_IT(g_tLiteLog.tpUart->tpDmaRx, DMA_IT_HT);    //  关闭DMA半中断
  
  //  step3:任务通知
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  vTaskNotifyGiveFromISR(xTaskHandle_Cmd,&xHigherPriorityTaskWoken);    //Miaozi：通知并唤醒控制台任务
  portYIELD_FROM_ISR( xHigherPriorityTaskWoken );                      

  return;
}

/***************************** LiteBsp by Miaozi (END OF FILE) *********************************/


